feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs - #2764
feat: Introduce Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs#2764reczkok wants to merge 10 commits into
Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs#2764Conversation
657340d to
2a31791
Compare
|
pkg.pr.new packages benchmark commit |
Resolution Time Benchmark---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.86, 1.64, 3.29, 5.21, 6.65, 9.46, 18.84, 19.19]
line [0.76, 1.68, 3.26, 5.52, 6.15, 9.92, 18.30, 18.42]
line [0.89, 1.67, 3.21, 5.52, 6.13, 8.97, 18.70, 20.80]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.27, 0.42, 0.62, 0.70, 0.93, 1.00, 1.21, 1.50]
line [0.29, 0.48, 0.57, 0.73, 1.00, 1.04, 1.23, 1.29]
line [0.27, 0.50, 0.61, 0.83, 1.07, 1.10, 1.68, 1.44]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.67, 1.79, 3.71, 5.53, 11.09, 22.11, 45.86, 92.39]
line [0.83, 1.75, 3.17, 5.58, 10.22, 22.25, 47.56, 93.95]
line [0.83, 1.73, 3.68, 6.18, 11.37, 22.23, 46.17, 94.81]
|
Bundle size comparison (
|
| 🟢 Decreased | ➖ Unchanged | 🔴 Increased (max 1.37%) | ❔ Unknown |
|---|---|---|---|
| 0 | 37 | 285 | 0 |
import * as ... in PR vs import * as ... in target (did bundle size increase?):
Click to reveal the results table (183 entries).
| Test | tsdown |
|---|---|
| STATIC_tgpu.ts | 272.89 kB ( |
| tgpu_fn.ts | 272.89 kB ( |
| tgpu_init.ts | 272.89 kB ( |
| tgpu_lazy.ts | 272.89 kB ( |
| tgpu_slot.ts | 272.89 kB ( |
| tgpu_const.ts | 272.90 kB ( |
| tgpu_unroll.ts | 272.90 kB ( |
| tgpu_resolve.ts | 272.90 kB ( |
| tgpu_accessor.ts | 272.90 kB ( |
| tgpu_comptime.ts | 272.90 kB ( |
| tgpu_vertexFn.ts | 272.90 kB ( |
| tgpu_computeFn.ts | 272.90 kB ( |
| tgpu_fragmentFn.ts | 272.90 kB ( |
| tgpu_privateVar.ts | 272.90 kB ( |
| tgpu_vertexLayout.ts | 272.90 kB ( |
| tgpu_workgroupVar.ts | 272.90 kB ( |
| tgpu_initFromDevice.ts | 272.90 kB ( |
| tgpu_bindGroupLayout.ts | 272.91 kB ( |
| tgpu_mutableAccessor.ts | 272.91 kB ( |
| tgpu_resolveWithContext.ts | 272.91 kB ( |
| STATIC_allImports.ts | 298.66 kB ( |
| d_bool.ts | 13.66 kB ( |
| d_f16.ts | 13.66 kB ( |
| d_f32.ts | 13.66 kB ( |
| d_i32.ts | 13.66 kB ( |
| d_u32.ts | 13.66 kB ( |
| d_u16.ts | 13.68 kB ( |
| d_textureDepth2d.ts | 14.10 kB ( |
| d_textureDepthCube.ts | 14.11 kB ( |
| d_texture1d.ts | 14.11 kB ( |
| d_texture2d.ts | 14.11 kB ( |
| d_texture3d.ts | 14.11 kB ( |
| d_textureCube.ts | 14.12 kB ( |
| d_textureDepth2dArray.ts | 14.12 kB ( |
| d_textureDepthCubeArray.ts | 14.12 kB ( |
| d_textureDepthMultisampled2d.ts | 14.13 kB ( |
| d_texture2dArray.ts | 14.13 kB ( |
| d_textureCubeArray.ts | 14.13 kB ( |
| d_textureMultisampled2d.ts | 14.14 kB ( |
| std_discard.ts | 14.95 kB ( |
| std_isBeingTranspiled.ts | 15.05 kB ( |
| std_getTargetShaderLanguage.ts | 15.11 kB ( |
| std_extensionEnabled.ts | 15.16 kB ( |
| std_copy.ts | 15.19 kB ( |
| std_arrayLength.ts | 15.20 kB ( |
| std_range.ts | 15.43 kB ( |
| d_disarrayOf.ts | 15.60 kB ( |
| std_dpdx.ts | 15.91 kB ( |
| std_dpdxCoarse.ts | 15.92 kB ( |
| std_dpdxFine.ts | 15.92 kB ( |
| std_dpdy.ts | 15.92 kB ( |
| std_dpdyCoarse.ts | 15.92 kB ( |
| std_dpdyFine.ts | 15.92 kB ( |
| std_fwidth.ts | 15.92 kB ( |
| std_fwidthCoarse.ts | 15.92 kB ( |
| std_fwidthFine.ts | 15.92 kB ( |
| std_atomicLoad.ts | 16.71 kB ( |
| std_atomicStore.ts | 16.72 kB ( |
| std_textureBarrier.ts | 16.72 kB ( |
| std_atomicAdd.ts | 16.72 kB ( |
| std_atomicAnd.ts | 16.72 kB ( |
| std_atomicMax.ts | 16.72 kB ( |
| std_atomicMin.ts | 16.72 kB ( |
| std_atomicOr.ts | 16.72 kB ( |
| std_atomicSub.ts | 16.72 kB ( |
| std_atomicXor.ts | 16.72 kB ( |
| std_storageBarrier.ts | 16.72 kB ( |
| std_workgroupBarrier.ts | 16.72 kB ( |
| d_vec2b.ts | 20.10 kB ( |
| d_vec2f.ts | 20.10 kB ( |
| d_vec2h.ts | 20.10 kB ( |
| d_vec2i.ts | 20.10 kB ( |
| d_vec2u.ts | 20.10 kB ( |
| d_vec3b.ts | 20.10 kB ( |
| d_vec3f.ts | 20.10 kB ( |
| d_vec3h.ts | 20.10 kB ( |
| d_vec3i.ts | 20.10 kB ( |
| d_vec3u.ts | 20.10 kB ( |
| d_vec4b.ts | 20.10 kB ( |
| d_vec4f.ts | 20.10 kB ( |
| d_vec4h.ts | 20.10 kB ( |
| d_vec4i.ts | 20.10 kB ( |
| d_vec4u.ts | 20.10 kB ( |
| d_formatToWGSLType.ts | 21.59 kB ( |
| d_uint8.ts | 21.60 kB ( |
| d_float16.ts | 21.60 kB ( |
| d_float16x2.ts | 21.60 kB ( |
| d_float16x4.ts | 21.60 kB ( |
| d_float32.ts | 21.60 kB ( |
| d_float32x2.ts | 21.60 kB ( |
| d_float32x3.ts | 21.60 kB ( |
| d_float32x4.ts | 21.60 kB ( |
| d_sint16.ts | 21.60 kB ( |
| d_sint16x2.ts | 21.60 kB ( |
| d_sint16x4.ts | 21.60 kB ( |
| d_sint32.ts | 21.60 kB ( |
| d_sint32x2.ts | 21.60 kB ( |
| d_sint32x3.ts | 21.60 kB ( |
| d_sint32x4.ts | 21.60 kB ( |
| d_sint8.ts | 21.60 kB ( |
| d_sint8x2.ts | 21.60 kB ( |
| d_sint8x4.ts | 21.60 kB ( |
| d_snorm16.ts | 21.60 kB ( |
| d_snorm16x2.ts | 21.60 kB ( |
| d_snorm16x4.ts | 21.60 kB ( |
| d_snorm8.ts | 21.60 kB ( |
| d_snorm8x2.ts | 21.60 kB ( |
| d_snorm8x4.ts | 21.60 kB ( |
| d_uint16.ts | 21.60 kB ( |
| d_uint16x2.ts | 21.60 kB ( |
| d_uint16x4.ts | 21.60 kB ( |
| d_uint32.ts | 21.60 kB ( |
| d_uint32x2.ts | 21.60 kB ( |
| d_uint32x3.ts | 21.60 kB ( |
| d_uint32x4.ts | 21.60 kB ( |
| d_uint8x2.ts | 21.60 kB ( |
| d_uint8x4.ts | 21.60 kB ( |
| d_unorm10_10_10_2.ts | 21.60 kB ( |
| d_unorm16.ts | 21.60 kB ( |
| d_unorm16x2.ts | 21.60 kB ( |
| d_unorm16x4.ts | 21.60 kB ( |
| d_unorm8.ts | 21.60 kB ( |
| d_unorm8x2.ts | 21.60 kB ( |
| d_unorm8x4.ts | 21.60 kB ( |
| d_unorm8x4_bgra.ts | 21.60 kB ( |
| d_packedFormats.ts | 21.62 kB ( |
| d_isPackedData.ts | 21.67 kB ( |
| d_alignmentOf.ts | 22.55 kB ( |
| std_subgroupAdd.ts | 25.05 kB ( |
| std_subgroupAll.ts | 25.05 kB ( |
| std_subgroupAnd.ts | 25.05 kB ( |
| std_subgroupAny.ts | 25.05 kB ( |
| std_subgroupBallot.ts | 25.05 kB ( |
| std_subgroupBroadcast.ts | 25.05 kB ( |
| std_subgroupBroadcastFirst.ts | 25.05 kB ( |
| std_subgroupElect.ts | 25.05 kB ( |
| std_subgroupExclusiveAdd.ts | 25.05 kB ( |
| std_subgroupExclusiveMul.ts | 25.05 kB ( |
| std_subgroupInclusiveAdd.ts | 25.05 kB ( |
| std_subgroupInclusiveMul.ts | 25.05 kB ( |
| std_subgroupMax.ts | 25.05 kB ( |
| std_subgroupMin.ts | 25.05 kB ( |
| std_subgroupMul.ts | 25.05 kB ( |
| std_subgroupOr.ts | 25.05 kB ( |
| std_subgroupShuffle.ts | 25.05 kB ( |
| std_subgroupShuffleDown.ts | 25.05 kB ( |
| std_subgroupShuffleUp.ts | 25.05 kB ( |
| std_subgroupShuffleXor.ts | 25.05 kB ( |
| std_subgroupXor.ts | 25.05 kB ( |
| d_isBuiltin.ts | 25.28 kB ( |
| d_sizeOf.ts | 25.33 kB ( |
| d_isContiguous.ts | 25.33 kB ( |
| d_getLongestContiguousPrefix.ts | 25.35 kB ( |
| std_textureDimensions.ts | 26.66 kB ( |
| std_textureGather.ts | 26.66 kB ( |
| std_textureLoad.ts | 26.67 kB ( |
| std_textureSample.ts | 26.67 kB ( |
| std_textureSampleBaseClampToEdge.ts | 26.67 kB ( |
| std_textureSampleBias.ts | 26.67 kB ( |
| std_textureSampleCompare.ts | 26.67 kB ( |
| std_textureSampleCompareLevel.ts | 26.67 kB ( |
| std_textureSampleGrad.ts | 26.67 kB ( |
| std_textureSampleLevel.ts | 26.67 kB ( |
| std_textureStore.ts | 26.67 kB ( |
| d_arrayOf.ts | 26.77 kB ( |
| d_size.ts | 27.01 kB ( |
| d_align.ts | 27.02 kB ( |
| d_location.ts | 27.02 kB ( |
| d_interpolate.ts | 27.02 kB ( |
| d_invariant.ts | 27.39 kB ( |
| std_identity2.ts | 27.71 kB ( |
| std_identity3.ts | 27.71 kB ( |
| std_rotationX4.ts | 27.71 kB ( |
| std_rotationY4.ts | 27.71 kB ( |
| std_rotationZ4.ts | 27.71 kB ( |
| std_scaling4.ts | 27.71 kB ( |
| std_translation4.ts | 27.71 kB ( |
| std_identity4.ts | 27.71 kB ( |
| d_mat4x4f.ts | 27.72 kB ( |
| d_mat2x2f.ts | 27.72 kB ( |
| d_mat3x3f.ts | 27.72 kB ( |
| d_matToArray.ts | 27.85 kB ( |
| d_builtin.ts | 29.23 kB ( |
import { ... } in PR vs import * as ... in PR (is the library tree-Shakeable?):
| Test | tsdown |
|---|---|
| tgpu_init.ts | 264.14 kB ( |
| tgpu_initFromDevice.ts | 263.61 kB ( |
| tgpu_resolve.ts | 167.18 kB ( |
| tgpu_resolveWithContext.ts | 167.11 kB ( |
| tgpu_bindGroupLayout.ts | 71.68 kB ( |
| tgpu_mutableAccessor.ts | 68.08 kB ( |
| tgpu_accessor.ts | 68.07 kB ( |
| tgpu_privateVar.ts | 66.81 kB ( |
| tgpu_workgroupVar.ts | 66.81 kB ( |
| tgpu_const.ts | 66.29 kB ( |
| tgpu_lazy.ts | 66.17 kB ( |
| tgpu_fn.ts | 38.62 kB ( |
| tgpu_fragmentFn.ts | 38.62 kB ( |
| tgpu_vertexFn.ts | 38.43 kB ( |
| tgpu_computeFn.ts | 38.14 kB ( |
| tgpu_vertexLayout.ts | 27.25 kB ( |
| tgpu_comptime.ts | 14.94 kB ( |
| tgpu_unroll.ts | 1.66 kB ( |
| tgpu_slot.ts | 1.54 kB ( |
If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.
Tgpu(RenderPass/ComputePass/CommandEncoder) and remove the old callback based APIs
There was a problem hiding this comment.
Pull request overview
This PR replaces the old callback-based experimental pass APIs with typed command encoder/pass abstractions (TgpuCommandEncoder, TgpuRenderPass, TgpuComputePass) to support batching, better state management, and deferred log/timestamp processing across submissions.
Changes:
- Introduces typed command encoders/passes and render bundle encoders, and rewires pipelines to target typed passes/encoders (or adopted raw WebGPU objects).
- Centralizes draw/dispatch state tracking (deduplication, “raw access disables dedup”, executeBundles reset behavior), and defers shader-log draining + timestamp resolve to encoder submission.
- Updates tests and docs to the new APIs; upgrades
@webgpu/typescatalog version.
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-workspace.yaml | Bumps @webgpu/types catalog version. |
| pnpm-lock.yaml | Lockfile updates for @webgpu/types@0.1.71. |
| packages/typegpu/tests/tgsl/shellless.test.ts | Adds regression test for mixed void/value return type detection. |
| packages/typegpu/tests/root.test.ts | Migrates render-pass tests to createCommandEncoder/typed pass flow. |
| packages/typegpu/tests/renderPipeline.test.ts | Updates error messaging + adds new behavior tests for pass defaults and bundle-pass binding. |
| packages/typegpu/tests/guardedComputePipeline.test.ts | Adds batching safety tests for guarded dispatch sizing. |
| packages/typegpu/tests/computePipeline.test.ts | Adds tests for log draining, timestamp deferral, and raw-encoder warnings. |
| packages/typegpu/tests/commandEncoder.test.ts | New comprehensive test suite for typed command encoder/pass state behavior. |
| packages/typegpu/src/unwrapper.ts | Extends unwrap overloads to include typed command encoder and passes. |
| packages/typegpu/src/tgsl/wgslGenerator.ts | Reports void return types consistently for bare return; to enable mixed-return detection. |
| packages/typegpu/src/tgsl/consoleLog/types.ts | Clarifies log-count limit semantics across encoder-batched workloads. |
| packages/typegpu/src/shared/warnOnce.ts | Adds shared warnOnce helper for deduplicated warnings. |
| packages/typegpu/src/indexNamedExports.ts | Exposes new command encoder/pass-related types from the public entrypoint. |
| packages/typegpu/src/core/texture/texture.ts | Tracks view format/aspect in internals for attachment-default inference. |
| packages/typegpu/src/core/root/rootTypes.ts | Replaces old callback-based pass APIs with typed encoder/pass API definitions. |
| packages/typegpu/src/core/root/init.ts | Implements createCommandEncoder/createRenderBundleEncoder; updates unwrap logic; adds guarded-dispatch tracking hooks. |
| packages/typegpu/src/core/pipeline/typeGuards.ts | Adds TypeGPU command/pass guards and strengthens raw WebGPU encoder/pass detection. |
| packages/typegpu/src/core/pipeline/timeable.ts | Defers timestamp resolution/callback invocation to encoder submission; dedupes resolve + warns on repeated timed executions. |
| packages/typegpu/src/core/pipeline/renderPipeline.ts | Refactors draw execution to use typed passes/encoders and shared draw-state machinery. |
| packages/typegpu/src/core/pipeline/drawState.ts | New shared render/compute state tracking + log/timestamp deferral + raw-surface warnings. |
| packages/typegpu/src/core/pipeline/connectAttachmentToShader.ts | Treats void fragment outputs as “no color attachments”. |
| packages/typegpu/src/core/pipeline/computePipeline.ts | Refactors dispatch execution to use typed passes/encoders and shared draw-state machinery. |
| packages/typegpu/src/core/pipeline/applyPipelineState.ts | Removes old “apply pipeline state” helper (superseded by drawState.ts). |
| packages/typegpu/src/core/commandEncoder/renderPass.ts | New typed render pass + render bundle encoder implementations, including attachment normalization/defaults. |
| packages/typegpu/src/core/commandEncoder/computePass.ts | New typed compute pass implementation. |
| packages/typegpu/src/core/commandEncoder/commandEncoder.ts | New typed command encoder implementation with submit/finish hooks. |
| packages/typegpu/src/core/commandEncoder/attachments.ts | Shared attachment types + unwrapping helpers for typed pass descriptors. |
| packages/typegpu-testing-utility/src/extendedIt.ts | Adjusts test harness to mock createRenderBundleEncoder and expose bundle encoder fixture earlier. |
| packages/typegpu-gl/src/tgpuRootWebGL.ts | Updates WebGL fallback surface for the renamed bundle encoder API (but currently misses createCommandEncoder). |
| apps/typegpu-docs/src/examples/rendering/simple-shadow/index.ts | Migrates example to typed command encoder/passes. |
| apps/typegpu-docs/src/examples/rendering/render-bundles/index.ts | Migrates bundle recording and per-frame render pass to new APIs. |
| apps/typegpu-docs/src/examples/rendering/render-bundles-with/index.ts | Migrates example to typed command encoder submission. |
| apps/typegpu-docs/src/content/docs/apis/pipelines.mdx | Rewrites docs section to describe command encoders/passes and new execution modes. |
| apps/typegpu-docs/src/content/docs/advanced/timestamp-queries.mdx | Documents performance callbacks behavior with typed command encoders vs shared passes. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — introduces TgpuCommandEncoder, TgpuRenderPass, TgpuComputePass, and TgpuRenderBundleEncoder as typed wrappers around WebGPU's encoder/pass primitives, replacing the old callback-based beginRenderPass/beginRenderBundleEncoder APIs. Refactors pipeline dispatch to use the new typed passes, consolidates draw state management into drawState.ts, moves attachment types into attachments.ts, and adds a warnOnce utility for deduplicated warnings.
- Typed command encoder and passes —
createCommandEncoder,beginRenderPass,beginComputePassonExperimentalTgpuRoot;TgpuCommandEncoder,TgpuRenderPass,TgpuComputePass,TgpuRenderBundleEncodernew public types - Pipeline dispatch refactor — both render and compute pipelines redirect through
#execute→emitRenderDraw/emitComputeDispatch;#withPriorshelper consolidateswith()chain mutation - Draw state and deduplication —
RenderDrawState/ComputeDrawStateclasses with version counters; state re-applied on the raw pass only when changed or afterunwrapping - Attachment defaults —
beginRenderPassderivesloadOp/storeOp/depthClearValuedefaults from texture format and view aspect;ColorAttachment/DepthStencilAttachmentmoved from render pipeline toattachments.ts - Timestamp resolution — deferred to the encoder's
beforeFinishhook viaqueueTimestampResolve; callbacks fire once per submission; repeated timed executions within one encoder warn warnOnceutility —WeakMap<object, Set<string>>deduplicates warnings per key; used for attachments, timestamps, logs, and guarded dispatch size mismatchesTgpuGuardedComputePipeline— tracks batched dispatch sizes per encoder/pass; rejects differently-sized dispatches in one submission@webgpu/typesbump — 0.1.69 → 0.1.71- Old API removal —
beginRenderPass/beginRenderBundleEncodercallbacks,RenderPass/RenderBundleEncoderPasstypes,applyPipelineState.ts,_lastAppliedRender/_lastAppliedComputeweak maps
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
8870379 to
b1d046f
Compare
b1d046f to
9a541a7
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — commit 9a541a71 integrates the standalone warnOnce utility into TgpuLogger, switches all call sites to use logger.warnOnce('suspicious', ...), and adds the missing createCommandEncoder surface to the WebGL fallback.
warnOnceinTgpuLogger—shared/warnOnce.tsdeleted;TgpuLoggergainswarnOnce(type, key, tag, ...args)with the same dedup semantics plus warning-type gating (silenced in production)- Per-root dedup for
finish()— key changed from the encoder instance toroot, so the "use submit()" warning fires at most once per root - WebGL fallback —
TgpuRootWebGLnow hascreateCommandEncoder()that throwsWebGLFallbackUnsupportedError - Test hardening —
vi.spyOn→usingin two compute pipeline tests; new test for per-root warning dedup across encoders; newwarnOnceunit tests for the logger (once-per-key-and-tag, disabled-type behavior)
DeepSeek Pro (free via Pullfrog for OSS) (Kimi K2 not used — the program covers this model; add its provider key to run your pick) | 𝕏
aleksanderkatan
left a comment
There was a problem hiding this comment.
Great changes! I think the new API is intuitive.
I didn't manage to review the entire thing.
There was a problem hiding this comment.
I will open an issue, not a priority for me now
There was a problem hiding this comment.
Can we add a note in docs that the API mixing may be unintuitive?
const encoder = root['~unstable'].createCommandEncoder();
const pass = encoder.beginComputePass();
pass.setPipeline(pipelineA);
pipelineB.with(pass).dispatchWorkgroups(1);
pass.dispatchWorkgroups(1);
pass.end();
encoder.submit(); // "B" is printed twiceThere was a problem hiding this comment.
Added a note, take a look
| import type { TgpuUniform } from '../buffer/bufferBinding.ts'; | ||
| import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts'; | ||
| import { | ||
| INTERNAL_beginComputePass, |
There was a problem hiding this comment.
Which functions exactly should be prefixed with "INTERNAL_"? For example, why is INTERNAL_adoptRenderCommands named like that?
There was a problem hiding this comment.
INTERNAL_adoptRenderCommands is named that because it's called from renderPipeline.ts's .with(rawPass) which is an internal api and not user facing. Seems consistent to me
There was a problem hiding this comment.
Or at least consistently inconsistent with existing convention across repo
|
|
||
| expect(renderPassEncoder.setPipeline).toBeCalledTimes(3); | ||
| }); | ||
|
|
There was a problem hiding this comment.
is this intended behavior?
it('re-applies pipeline state? ', ({ root, renderPassEncoder }) => {
const group = root.createBindGroup(layout, {
foo: root.createBuffer(d.f32).$usage('uniform'),
});
const first = root
.createRenderPipeline({ vertex: mainVertex, fragment: mainFragment })
.with(group);
const encoder = root.createCommandEncoder();
const pass = encoder.beginRenderPass({ colorAttachments: [] });
first.with(pass).draw(3);
first.with(pass).draw(3);
first.with(pass).draw(3);
pass.end();
encoder.submit();
expect(renderPassEncoder.setPipeline).toBeCalledTimes(3);
});There was a problem hiding this comment.
it's fine for now, we can add dedupe mechanism in the future
| plain.with(pass).draw(3); | ||
| pass.end(); | ||
| encoder.submit(); | ||
|
|
There was a problem hiding this comment.
I find the behavior of bindGroups and stencilReferences inconsistent
pass.setBindGroup(passGroup);
pipeline.with(pass).draw(3);
pass.end();
encoder.submit();
expect(renderPassEncoder.setBindGroup).toBeCalledTimes(1);
expect(renderPassEncoder.setBindGroup).toBeCalledWith(0, root.unwrap(pipelineGroup));I don't think that pass.setStencilReference(7); should be called.
…ery much in ga example), I also rewrote ga to not use guarded, the inefficiency bugged me too much, sry
8de9da9 to
3f1f2d1
Compare
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — commit 8de9da9c builds on the typed encoder/pass API by integrating buffers with command encoders, adding typed indirect draw/dispatch support, simplifying the guarded compute pipeline contract, and updating docs/examples.
- Buffer encoder integration —
TgpuBuffer.clear(encoder?)andTgpuBuffer.copyFrom(src, encoder?)now record into an optionalTgpuCommandEncoderinstead of always submitting immediately; tests verify the command is deferred untilencoder.submit() - Typed indirect dispatches and draws —
dispatchWorkgroupsIndirect,drawIndirect, anddrawIndexedIndirectacceptTgpuBuffer<...> & IndirectFlagplus aPrimitiveOffsetInfoor numeric offset; a sharedresolveIndirectOffsethelper validates alignment, buffer bounds, and contiguous-byte padding inpipelineUtils.ts - Guarded pipeline simplification —
TgpuGuardedComputePipeline.with()now only accepts bind groups and dispatches immediately on eachdispatchThreads()call; the previous batched-size tracking for encoders/passes was removed, matching the documented limitation - Genetic-racing example rewrite — switched from guarded pipelines to regular compute pipelines batched into typed compute passes, avoiding the guarded-pipeline overhead while using the new encoder APIs
- Docs and examples — updated
buffers.mdx,pipelines.mdx, andtimestamp-queries.mdxwith the new encoder examples; migratedrender-bundles,render-bundles-with, andsimple-shadowexamples to the typed command encoder/pass flow - WebGL fallback — renamed the unsupported-method stubs from the old callback API to
createCommandEncoder/createRenderBundleEncoder - Test hardening — replaced
toBeCalled*withtoHaveBeenCalled*across the new command-encoder tests and addedusingforconsole.warnspies; buffer tests cover the new encoder variants
Validation run: pnpm vitest run --project=!browser packages/typegpu/tests/{buffer,commandEncoder,computePipeline,renderPipeline,guardedComputePipeline,root}.test.ts (199 tests passed) and pnpm --filter typegpu test:types both pass.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the latest push (8de9da9c → 3f1f2d16) is a rebase onto a newer main. The PR-specific typed encoder/pass changes are unchanged from the prior review.
I re-ran the targeted test suite on the new head and verified the same behavior:
pnpm vitest run --project=!browser packages/typegpu/tests/{buffer,commandEncoder,computePipeline,renderPipeline,guardedComputePipeline,root}.test.ts— 199 tests passedpnpm --filter typegpu test:types— passes
No new PR-specific concerns.
Kimi K2 (free via Pullfrog for OSS) | 𝕏


Why is this PR?
In short apart from introducing typed variants of the pass/encoder APIs they also give us more freedom and control for future extensions and clean up the pipeline APIs (moves the complexity elsewhere tbh). This will allow/already achieves:
I also rewrote the beginRenderBundleEncoder API to match the new conventions since it followed the old render pass callback based API (which also is removed as part of this PR). This is a breaking change ❗ but I think fair game since it's unstable. Keeping it around would be inconsistent imo
The
warnOncefeature is now integrated with the logger from #2747.